﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BoYuanCore.CodeGenerator.code;
using BoYuanCore.CoreCodeTemplates;
using BoYuanCore.CoreCodeTemplates.FineUICore.Template;
using BoYuanCore.DBD;
using BoYuanCore.DBD.Entity;
using FineUIPro;
using FreeSql;
using HtmlAgilityPackInternal;
using DbColumnInfo = BoYuanCore.CoreCodeTemplates.DbColumnInfo;

namespace BoYuanCore.CodeGenerator.FineuiCore
{
    public partial class SetFineuiProCode : CodeBasePage
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                // var db = BoYuan.DBD.DBServices.Instance ;
                // var list = db.Queryable<VSProject>().ToList() ;
                // ddl_vsProject.BindByDataSource(list,nameof(VSProject.ProjectName),nameof(VSProject.id));


                //web项目admin文件夹路径 D:\项目\BoYuanCore\BoYuanCore.Web\Areas\Admin\Views
                string pathAdmin = Path.GetFullPath(Server.MapPath("~/") + @"..\..\" + txb_NameSpace.Text + @"\" + txb_NameSpace.Text + @".Web\Areas\" + txb_Areas.Text + @"\Views");
                f_moudelUrl.Text = pathAdmin;
            }
        }

        protected void Btn_SetSimpleCode_OnClick(object sender, EventArgs e)
        {
            var tables = hd_tables.Text.Split(',');
            if (hd_tables.Text.Length == 0 || tables.Length == 0)
            {
                NotifyError("获取表集合失败！");
                return;
            }


            if (!Directory.Exists(txb_savePath.Text))
            {
                Directory.CreateDirectory(txb_savePath.Text); //建立文件夹
            }

            try
            {
                foreach (string item in tables)
                {
                    SetCodeByTableName(item);
                }
            }
            catch (Exception exception)
            {
                NotifyError(exception.Message);
                return;
            }

            NotifyInformation("生成简单代码成功!");
        }

        /// <summary>
        /// 生成页面代码，根据表
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        private void SetCodeByTableName(string tableName)
        {
            try
            {
                List<DbColumnInfo> cm = GetColumnDataByTableName(tableName);//字段信息集合

                string namespace2Str = txb_Areas.Text.Trim().Replace("/", ".");

                string savePath = txb_savePath.Text.Trim();

                TableModel table = new TableModel();
                table.Columns = cm;
                table.ClassnameStr = txb_BaseClassName.Text;
                table.NamespaceStr = txb_NameSpace.Text + ".Web";
                table.Namespace2Str = namespace2Str;
                table.ModelName = txb_NameSpace.Text + ".Entities";
                table.TableName = tableName;
                table.DbClass = Session["dbtype"].ToString();

                CreateFineUICoreCode(savePath, table, cb_isHaveAddPage.Checked, cb_isHaveGridPage.Checked, cb_isHaveViewPage.Checked, cb_isHaveEGPage.Checked, cb_isHaveOnePage.Checked);
            }
            catch (Exception ex)
            {
                throw new Exception("生成代码有问题：表名称(" + tableName + ")" + ex.Message);
            }

        }


        protected void Btn_AddPageInfoToDB_OnClick(object sender, EventArgs e)
        {

            //遍历项目文件到指定
            IOrderedEnumerable<DirectoryInfo> dirList = GetViewDirInfo(out var error);
            if (error)
            {
                NotifyError("项目页面路径不正确,请手动选择！");
                return;
            }

            using (var db = MyInstance())
            {
                int maxId = db.Select<SysModule>().OrderByDescending(p => p.ID).First(p => p.ID);
                
                List<SysModule> moduleList = new List<SysModule>();
                IEnumerable<FileInfo> cshtmlList;
                SysModule mo;
                foreach (var dir in dirList)
                {
                    cshtmlList = dir.EnumerateFiles("*.cshtml").OrderBy(p => p.Name);

                    foreach (var cshtml in cshtmlList)
                    {
                        string url = (txb_Areas.Text.Trim() + "/" + dir + "/" + cshtml.Name.Replace(".cshtml", string.Empty)).ToLower();
                        if (!db.Select<SysModule>().Where(p => p.Url == url).Any())
                        {
                            mo = new SysModule();
                            mo.ParentID = 0;
                            mo.TreePath = "0,";
                            mo.PageTitle = dir.Name;
                            mo.Url = url;
                            mo.FontIcon = string.Empty;
                            mo.Icon = string.Empty;
                            mo.Sort = 1000;
                            mo.IsHidden = true;
                            mo.Remark = string.Empty;
                            mo.ID = ++maxId;//不使用雪花实体生成的id，为了减少长度
                            moduleList.Add(mo);
                        }
                    }
                }

                if (moduleList.Count == 0)
                {
                    NotifyInformation("暂无同步页面！");
                    return;
                }

                db.Insert(moduleList).ExecuteAffrows();
                NotifyInformation(string.Format("添加了{0}条数据，请根据业务逻辑更改页面组件数据!", moduleList.Count));

            }
        }

        protected void Btn_AddButtonInfoToDB_OnClick(object sender, EventArgs e)
        {
            /*
            //button同步到数据库中
            IOrderedEnumerable<DirectoryInfo> dirList = GetAspxDirInfo(out var error);
            if (error)
            {
                NotifyError("项目页面路径不正确,请手动选择！");
                return;
            }

            var db = MyInstance();
            long maxId = db.Select<Entity.SysButtonModule>().OrderByDescending(p => p.ID).First(p => p.ID);

            List<SysButtonModule> moduleList = new List<SysButtonModule>();
            IEnumerable<FileInfo> aspxList;
            SysButtonModule module;
            string tempStr;
            HtmlAgilityPack.HtmlDocument doc;
            HtmlNodeCollection nodes;
            HtmlNode node;
            string buttonId = string.Empty, buttonText = string.Empty;
            foreach (var dir in dirList)
            {
                aspxList = dir.EnumerateFiles("*.aspx").OrderBy(p => p.Name);
                foreach (var aspx in aspxList)
                {
                    tempStr = File.ReadAllText(aspx.FullName);
                    //由于f:Button xpath 不能正常获取，需要转成fineuibutton。注意xpath不支持大写
                    tempStr = tempStr.Replace("f:Button", "fineuibutton");
                 
                    doc = new HtmlAgilityPack.HtmlDocument();
                    doc.LoadHtml(tempStr);
                    nodes = doc.DocumentNode.SelectNodes("//fineuibutton");
                    if (nodes != null && nodes.Count > 0)
                    {
                        for (int i = 0; i < nodes.Count; i++)
                        {
                            node = nodes[i];
                            foreach (var attr in node.Attributes)
                            {
                                switch (attr.Name)
                                {
                                    case "id":
                                        buttonId = attr.Value;
                                        break;
                                    case "text":
                                        buttonText = attr.Value;
                                        break;
                                }
                            }
                            module = GetSyncSysButtonModule(dir.Name, aspx.Name, buttonId, buttonText);
                            if (module != null)
                            {
                                module.ID = ++maxId;//不使用雪花实体生成的id，为了减少长度
                                moduleList.Add(module);
                            }
                        }
                    }
                }
            }

            if (moduleList.Count == 0)
            {
                NotifyInformation("暂无同步按钮！");
                return;
            }

            db.Insert(moduleList).ExecuteAffrows();
            NotifyInformation(string.Format("添加了{0}条数据，请根据业务逻辑更改按钮权限组件数据!", moduleList.Count));
            */
        }



        /*
        /// <summary>
        /// 获取要同步页面组件数据
        /// </summary>
        /// <param name="dir">文件夹</param>
        /// <param name="aspx">aspx页面</param>
        private SysButtonModule GetSyncSysButtonModule(string dir,string aspx,string buttonId,string buttonText)
        {
            if (buttonId.Length == 0) return null;//无按钮id，说明不需要权限控制

            string url = dir + "/" + aspx;
            var db = MyInstance();
            if (!db.Queryable<BoYuan.Entity.SysButtonModule>().Where(p => p.url == url).Any())
            {
                BoYuan.Entity.SysButtonModule mo =new SysButtonModule();
                mo.buttonID = buttonId;
                mo.buttonText = buttonText;
                mo.buttonStatus = (byte)BoYuan.EnumLib.SysButtonModule.buttonStatus.权限按钮;
                mo.url = url;
                mo.remark = string.Empty;

                return mo;
            }

            return null;
        }
         */

        /// <summary>
        /// 获取指定目录下的文件夹信息
        /// </summary>
        /// <param name="haveError">返回错误</param>
        /// <returns></returns>
        private IOrderedEnumerable<DirectoryInfo> GetViewDirInfo(out bool haveError)
        {
            //遍历项目文件到指定
            if (!Directory.Exists(f_moudelUrl.Text.Trim()))
            {
                haveError = true;
                return null;
            }

            //读取页面
            DirectoryInfo adminDir = new DirectoryInfo(f_moudelUrl.Text.Trim());
            IOrderedEnumerable<DirectoryInfo> dirList = adminDir.GetDirectories()
                .Where(p => !new List<string>()
                {
                    "home", "login"
                }.Contains(p.Name.ToLower()))
                .OrderBy(p => p.Name);

            haveError = false;
            return dirList;
        }



        protected void btn_ShowCode_OnClick(object sender, EventArgs e)
        {
            //显示单表FineuiPro代码
            var tables = hd_tables.Text.Split(',');
            if (hd_tables.Text.Length == 0 || tables.Length == 0)
            {
                NotifyError("获取表集合失败！");
                return;
            }
            string namespace2Str = txb_Areas.Text.Trim().Replace("/", ".");

            var tableName = tables[0];
            List<DbColumnInfo> cm = GetColumnDataByTableName(tableName);//字段信息集合  TableModel table=new TableModel();
            TableModel table = new TableModel();
            table.Columns = cm;
            table.ClassnameStr = txb_BaseClassName.Text;
            table.NamespaceStr = txb_NameSpace.Text + ".Web";
            table.Namespace2Str = namespace2Str;
            table.ModelName = txb_NameSpace.Text + ".Entity";
            table.TableName = tableName;

            //controllers
            string templateInfo = ControllerTemplate.GetCode(table, cb_isHaveAddPage.Checked, cb_isHaveGridPage.Checked, cb_isHaveViewPage.Checked, cb_isHaveEGPage.Checked, cb_isHaveOnePage.Checked);
            lb_Controller.Text = ShowHighlightCode(templateInfo);

            //add view
            templateInfo = AddcshtmlTemplate.GetCode(table);
            lb_Addcshtml.Text = ShowHighlightCode(templateInfo);

            //ListPage view
            templateInfo = ListPagecshtmlTemplate.GetCode(table);
            lb_ListPagecshtml.Text = ShowHighlightCode(templateInfo);

            PageContext.RegisterStartupScript("ShowHighlight();");
        }



        private void SyncCodeFirstDataByTableName(string tableName, int objId)
        {
            //todo 未实现
            AlertError("未实现"); return;
            /*
            var db = BoYuan.DBD.DBServices.Instance;
            var table= GetTableInfoByTableName(tableName) ;

            //同步表
            TableInfo tableInfo = db.Queryable<TableInfo>().Where(p => p.TableNameToClassName == tableName && p.objId == objId).First() ;
            if (tableInfo != null)//含有表 则更新
            {
                db.Updateable<TableInfo>()
                    .SetColumns(p => new TableInfo(){TableNameToClassName = table.Name, TableDescription = table.Comment}) 
                    .Where(p=>p.TableNameToClassName== tableName && p.objId==objId).ExecuteCommand();
            }
            else//否则添加
            {
                tableInfo=new TableInfo();
                tableInfo.TableNameToClassName = table.Name ;
                tableInfo.TableDescription = table.Comment;
                tableInfo.objId = objId ;
                tableInfo.id=BoYuan.DBD.DBServices.InsertModel(tableInfo) ;
            }

            //同步字段
            List<DbColumnInfo> cm = GetColumnDataByTableName(tableName);//字段信息集合
            if(cm!=null && cm.Count>0)
                for (int i = 0; i < cm.Count; i++)
                {
                    SyncCodeFirstDataByColumnName(cm[i], tableInfo) ;
                }
            */
        }

        /*
        private void SyncCodeFirstDataByColumnName(DbColumnInfo cm, TableInfo tableInfo)
        {
            //todo 未实现
            AlertError("未实现"); return;

            var db = BoYuan.DBD.DBServices.Instance;
            //同步表
            var column = db.Queryable<BoYuan.DBD.Entity.DbColumnInfo>()
                .Where(p => p.TableId==tableInfo.id
                       && p.objId == tableInfo.objId && p.DbColumnNameToClassName == cm.DbColumnNameToClassName).First() ;

            if (column!=null)//含有字段 则更新
            {
                column.DbColumnNameToClassName      = cm.DbColumnNameToClassName;
                column.objId             = tableInfo.objId;
                column.Coment = cm.Coment;
                column.DataType          = cm.DataType;
                column.DefaultValue      = cm.DefaultValue;
                column.IsIdentity        = cm.IsIdentity;
                column.TableId           = tableInfo.id;
                column.PropertyName      = cm.PropertyName;
                column.LengthValue       = cm.Length.ToString();
                column.IsNullable        = cm.IsNullable;
                column.IsPrimarykey      = cm.IsPrimarykey;

                BoYuan.DBD.DBServices.UpdateModelByKey(column);
            }
            else//否则添加
            {
                column = new BoYuan.DBD.Entity.DbColumnInfo() ;
                column.DbColumnNameToClassName      = cm.DbColumnNameToClassName ;
                column.objId             = tableInfo.objId ;
                column.Coment = cm.Coment??String.Empty;
                column.DataType          = cm.DataType ;
                column.DefaultValue      = cm.DefaultValue ;
                column.IsIdentity        = cm.IsIdentity ;
                column.TableId           = tableInfo.id;
                column.PropertyName      = cm.PropertyName;
                column.LengthValue       = cm.Length.ToString();
                column.IsNullable        = cm.IsNullable;
                column.IsPrimarykey      = cm.IsPrimarykey;

                BoYuan.DBD.DBServices.InsertModel(column);
            }
            
        }
        */

    }
}